#include "../../server/MessageManager.hpp"
#include <gtest/gtest.h>
#include <unordered_map>
#include <string>

micromq::MessageManager::ptr manager;

class MessageTest : public testing::Environment
{
public:
    virtual void SetUp() override
    {
        manager = std::make_shared<micromq::MessageManager>("./data");
        manager->addMessageCenter("q1");
        manager->addMessageCenter("q2");
        manager->addMessageCenter("q3");
    }

    virtual void TearDown() override
    {
        manager->clear();
    }
};

TEST(message_test, produce_test)
{
    micromq::BasicProperties properties;
    properties.set_id(micromq::UUIDHelper::getUUID());
    properties.set_mode(micromq::DeliveryMode::DURABLE);
    properties.set_routing_key("news.music.pop");

    manager->produceMessage("q1", &properties, "hello-1-1", micromq::DeliveryMode::DURABLE);
    manager->produceMessage("q1", nullptr, "hello-1-2", micromq::DeliveryMode::DURABLE);
    manager->produceMessage("q2", nullptr, "hello-2-1", micromq::DeliveryMode::DURABLE);
    manager->produceMessage("q2", nullptr, "hello-2-2", micromq::DeliveryMode::DURABLE);
    manager->produceMessage("q3", nullptr, "hello-3-1", micromq::DeliveryMode::UNDURABLE);

    ASSERT_EQ(manager->getTotalDurableNum("q1"), 2);
    ASSERT_EQ(manager->getTotalDurableNum("q2"), 2);
    ASSERT_EQ(manager->getTotalDurableNum("q3"), 0);

    ASSERT_EQ(manager->getValidDurableNum("q1"), 2);
    ASSERT_EQ(manager->getValidDurableNum("q2"), 2);
    ASSERT_EQ(manager->getValidDurableNum("q3"), 0);
}

TEST(message_test, consume_test)
{
    ASSERT_EQ(manager->getWaitConsumeNum("q1"), 2);
    ASSERT_EQ(manager->getWaitAckNum("q1"), 0);
    micromq::MessagePtr msg1 = manager->consumeMessage("q1");
    ASSERT_NE(msg1.get(), nullptr);
    ASSERT_EQ(manager->getWaitConsumeNum("q1"), 1);
    ASSERT_EQ(manager->getWaitAckNum("q1"), 1);
    ASSERT_EQ(msg1->payload().content(), std::string("hello-1-1"));
    manager->ackMessage("q1", msg1->payload().properties().id());
    ASSERT_EQ(manager->getWaitAckNum("q1"), 0);

    micromq::MessagePtr msg2 = manager->consumeMessage("q2");
    ASSERT_NE(msg2.get(), nullptr);
    ASSERT_EQ(msg2->payload().content(), std::string("hello-2-1"));
}

int main(int argc, char* argv[])
{
    testing::InitGoogleTest(&argc, argv);
    testing::AddGlobalTestEnvironment(new MessageTest);
    RUN_ALL_TESTS();

    return 0;
}